home *** CD-ROM | disk | FTP | other *** search
/ Scene Storm / Scene Storm - Volume 1.iso / coding / c / unix / src / kill.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-14  |  1.7 KB  |  75 lines

  1. #include "amiga.h"
  2. #include "signals.h"
  3. #include "processes.h"
  4. #include <exec/execbase.h>
  5.  
  6. extern struct ExecBase *SysBase;
  7.  
  8. static void break_list(struct List *tasks, BPTR fh)
  9. {
  10.   struct Process *p;
  11.  
  12.   for (p = (struct Process *)tasks->lh_Head; p->pr_Task.tc_Node.ln_Succ;
  13.        p = (struct Process *)p->pr_Task.tc_Node.ln_Succ)
  14.     {
  15.       if (p->pr_Task.tc_Node.ln_Type == NT_PROCESS)
  16.     {
  17.       struct CommandLineInterface *cli = p->pr_CLI ? BADDR(p->pr_CLI) : 0;
  18.  
  19.       if (p->pr_CIS == fh || p->pr_COS == fh || p->pr_CES == fh ||
  20.           cli && (cli->cli_StandardInput == fh || cli->cli_CurrentInput == fh ||
  21.               cli->cli_StandardOutput == fh || cli->cli_CurrentOutput == fh))
  22.         Signal(p, SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D);
  23.     }
  24.     }
  25. }
  26.  
  27. static int magickill(BPTR fh, int signo)
  28. {
  29.   switch (signo)
  30.     {
  31.     case SIGINT: case SIGQUIT: case SIGKILL: case SIGHUP:
  32.       Forbid();
  33.       break_list(&SysBase->TaskReady, fh);
  34.       break_list(&SysBase->TaskWait, fh);
  35.       Permit();
  36.       return 0;
  37.     default: errno = EINVAL; return -1;
  38.     }
  39. }
  40.  
  41. int kill(int pid, int signal)
  42. {
  43.   chkabort();
  44.   /* Our process list is now reasonably upto date */
  45.   if (pid < 0) pid = -pid;    /* Consider that each process is a pg unto itself */
  46.   if (pid == _our_pid) 
  47.     {
  48.       if (signal) _sig_dispatch(signal);
  49.       return 0;
  50.     }
  51.   else 
  52.     {
  53.       struct process *entry;
  54.       int killrc;
  55.  
  56.       entry = _find_pid(pid);
  57.       if (!entry || entry->status != alive)
  58.     {
  59.       errno = ESRCH;
  60.       return -1;
  61.     }
  62.       if (!signal) return 0;
  63.       killrc = magickill(entry->input, signal);
  64.       if (signal == SIGKILL)
  65.     {
  66.       /* Fake the kill from emacs point of view */
  67.       entry->status = exited;
  68.       entry->rc = SIGKILL;
  69.       _sig_dispatch(SIGCHLD);
  70.       return 0;
  71.     }
  72.       return killrc;
  73.     }
  74. }
  75.